# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

# Needed for linting targets, etc.
# Use the first Python installation on PATH, not the newest one
set(Python3_FIND_STRATEGY "LOCATION")
# On Windows, use registry last, not first
set(Python3_FIND_REGISTRY "LAST")
# On macOS, use framework last, not first
set(Python3_FIND_FRAMEWORK "LAST")

find_package(Python3)
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})

set(BUILD_SUPPORT_DIR "${PROJECT_SOURCE_DIR}/c++/build-support")

find_program(CLANG_FORMAT_BIN
        NAMES clang-format-13
        HINTS ${CLANG_SEARCH_PATH})

find_program(CLANG_TIDY_BIN
        NAMES clang-tidy-13
        HINTS ${CLANG_SEARCH_PATH})

find_program(CLANG_APPLY_REPLACEMENTS_BIN
        NAMES clang-apply-replacements-13
        HINTS ${CLANG_SEARCH_PATH})


if("${CLANG_FORMAT_BIN}" STREQUAL "CLANG_FORMAT_BIN-NOTFOUND")
        message(WARNING "Couldn't find clang-format.")
else()
        message(STATUS "Found clang-format at ${CLANG_FORMAT_BIN}")
endif()

if("${CLANG_TIDY_BIN}" STREQUAL "CLANG_TIDY_BIN-NOTFOUND")
        message(WARNING "Couldn't find clang-tidy.")
else()
        # Output compile_commands.json
        set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
        message(STATUS "Found clang-tidy at ${CLANG_TIDY_BIN}")
endif()

if("${CLANG_APPLY_REPLACEMENTS_BIN}" STREQUAL "CLANG_APPLY_REPLACEMENTS_BIN-NOTFOUND")
        message(WARNING "Couldn't find clang-apply-replacements.")
else()
        # Output compile_commands.json
        set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
        message(STATUS "Found clang-apply-replacements at ${CLANG_APPLY_REPLACEMENTS_BIN}")
endif()

if(NOT LINT_EXCLUSIONS_FILE)
        # source files matching a glob from a line in this file
        # will be excluded from linting (cpplint, clang-tidy, clang-format)
        set(LINT_EXCLUSIONS_FILE ${BUILD_SUPPORT_DIR}/lint_exclusions.txt)
endif()

# runs clang-tidy and exits with a non-zero exit code if any errors are found.
# note that clang-tidy automatically looks for a .clang-tidy file in parent directories
add_custom_target(check-clang-tidy
        ${PYTHON_EXECUTABLE}
        ${BUILD_SUPPORT_DIR}/run_clang_tidy.py # run LLVM's clang-tidy script
        -clang-tidy-binary ${CLANG_TIDY_BIN} # using our clang-tidy binary
        -p ${PROJECT_BINARY_DIR} # using cmake's generated compile commands
)

add_custom_target(fix-clang-tidy
        ${PYTHON_EXECUTABLE}
        ${BUILD_SUPPORT_DIR}/run_clang_tidy.py # run LLVM's clang-tidy script
        -clang-tidy-binary ${CLANG_TIDY_BIN} # using our clang-tidy binary
        -p ${PROJECT_BINARY_DIR} # using cmake's generated compile commands
        -clang-apply-replacements-binary ${CLANG_APPLY_REPLACEMENTS_BIN} # using our clang-apply-replacements binary
        -fix # apply suggested changes generated by clang-tidy
)

string(CONCAT ORC_FORMAT_DIRS
        "${PROJECT_SOURCE_DIR}/c++,"
        "${PROJECT_SOURCE_DIR}/tools,"
)

add_custom_target(format 
        ${PYTHON_EXECUTABLE}
        ${BUILD_SUPPORT_DIR}/run_clang_format.py
        ${CLANG_FORMAT_BIN}
        --source_dirs
        ${ORC_FORMAT_DIRS}
        --fix
)

# Runs clang format and exits with a non-zero exit code if any files need to be reformatted
add_custom_target(check-format 
        ${PYTHON_EXECUTABLE}
        ${BUILD_SUPPORT_DIR}/run_clang_format.py
        ${CLANG_FORMAT_BIN}
        --source_dirs
        ${ORC_FORMAT_DIRS}
)